package com.browsesoft.resource;

import java.util.*;

import com.browsesoft.user.User;

/**
 * 资源工具包
 */
public class ResourceTool {

	/**
	 * 取得资源某个属性的全路径，n表示去掉前面n级
	 * @param resource：资源
	 * @param field：字段
	 * @param n：去掉前面n级
	 * @return
	 */
	public static String getFullPathName(Resource resource, String field, int n) {
		StringBuilder name = new StringBuilder();
		List<String> names = new ArrayList<String>();

		// 把取得的内容存放在数组里
		while (resource != null) {
			String str = (String)resource.getAttributes().get(field);
			names.add(str);
			resource = resource.getParent();
		}

		// 按数组倒序，产生最后结果
		for (int i = names.size() - n - 1; i >= 0; i--) {
			if(name.length() != 0) {
				name.append('.');
			}
			name.append(names.get(i));
		}

		return name.toString();
	}

	/**
	 * 取得资源某个属性的全路径
	 *
	 * @param resource
	 *            资源
	 * @return 全名
	 */
	@Deprecated
	public static String getFullPathName(Resource resource, String field) {
		String name = "";
		while (resource != null) {
			name += resource.getAttributes().get(field) + ".";
			resource = resource.getParent();
		}
		name = name.substring(0, name.lastIndexOf("."));
		return name;
	}

	/**
	 * 取得资源的全名
	 * 
	 * @param resource
	 *            资源
	 * @return 全名
	 */
	@Deprecated
	public static String getFullPathName(Resource resource) {
		String result = getFullPathName(resource, "name");
		return result;
	}

	/**
	 * 看A资源对B资源有没有给定的权限
	 * 
	 * @param A
	 *            主动资源
	 * @param B
	 *            被动资源
	 * @param type
	 *            权限类型
	 * @return 有没有
	 */
	public static boolean hasRight(Resource A, Resource B, RightType type) {
		// 取得A对B的所有权限
		Collection list = getRights(A, B);
		// 对于每一个权限
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Right item = (Right) iter.next();
			// 如果与给定类型相同
			if (item.getType().equals(type)) {
				// 返回有
				return true;
			}
		}
		// 如果A是个用户
		if (A instanceof User) {
			// 得到用户的角色列表
			LinkedList roles = ((User) A).getRoles();
			Resource temp;
			for (int i = 0; i < roles.size(); i++) {
				temp = (Resource) roles.get(i);
				// 取得角色对B的所有权限
				list = getRights(temp, B);
				// 对于每一个权限
				iter = list.iterator();
				while (iter.hasNext()) {
					Right item = (Right) iter.next();
					// 如果与给定类型相同
					if (item.getType().equals(type)) {
						// 返回有
						return true;
					}
				}
			}
		}
		// 返回没有
		return false;
	}

	/**
	 * 取得A对B的所有权限
	 * 
	 * @param A
	 *            主动资源
	 * @param B
	 *            被动资源
	 * @return A对B的所有权限列表
	 */
	public static Collection getRights(Resource A, Resource B) {
		Collection result = new LinkedList();
		// 得到A的所有权限
		LinkedList list = A.getRights();
		// 对于每一个权限
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Right item = (Right) iter.next();
			// 如果被动资源等于B
			Resource res = item.getResource();
			if (res != null && res.equals(B)) {
				// 添加到结果中
				result.add(item);
			}
		}
		return result;
	}

	/**
	 * 取得A对B的所有权限
	 * 
	 * @param A
	 *            主动资源
	 * @param B
	 *            被动资源
	 * @return A对B的所有权限列表
	 */
	public static Collection getUserRights(User A, Resource B) {
		Collection result = new HashSet();
		result.addAll(getRights(A, B));
		// 得到用户的角色列表
		LinkedList roles = A.getRoles();
		Iterator iter = roles.iterator();
		while (iter.hasNext()) {
			Resource res = (Resource) iter.next();
			// 取得角色对B的所有权限
			result.addAll(getRights(res, B));
		}
		return result;
	}

	/**
	 * 在资源first后面增加资源second
	 * 
	 * @param first
	 *            在其后面增加
	 * @param second
	 *            要移动的资源
	 */
	public static void add(Resource first, Resource second) {
		try {
			// 得到第一个功能在其兄弟中的位置
			int location = first.getPosition();
			// 对于first的所有兄弟
			Iterator iter = first.getParent().getChildren();
			while (iter.hasNext()) {
				Resource item = (Resource) iter.next();
				// 得到在兄弟中的排行
				int funLocation = item.getPosition();
				// 如果比first大
				if (funLocation > location) {
					// 往后移动一个位置
					item.setPosition(funLocation + 1);
					item.update();
				}
			}
			// 取得要移动资源在兄弟中的位置
			second.setPosition(location + 1);
			// 子功能设置父功能
			Resource parent = first.getParent();
			second.getParent().removeChild(second);
			second.setParent(parent);
			second.update();
			// 增加资源
			parent.addChild(second);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public Collection getRoots(Collection resources) {
		Collection result = new HashSet();
		Iterator iter = resources.iterator();
		while (iter.hasNext()) {
			Resource item = (Resource) iter.next();
			Resource parent = item.getParent();
			while (parent != null && result.contains(parent)) {
				item = parent.getParent();
				parent = parent.getParent();
			}
			result.add(item);
		}
		return result;
	}

	/**
	 * 得到列表中所有资源的所有祖先,并且祖先不在列表中
	 */
	public static Collection getAllAncenstor(Collection list) {
		Collection result = new HashSet();
		// 对于给定列表中的每一个资源
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Resource item = (Resource) iter.next();
			// 将该资源的所有祖先添加到结果中
			Resource parent = item.getParent();
			while (parent != null) {
				if (!list.contains(parent)) {
					result.add(parent);
				}
				parent = parent.getParent();
			}
		}
		return result;
	}

	/**
	 * 看祖先资源是否包含某后代资源
	 */
	public static boolean contains(Resource ancestor, Resource descendant) {
		// 如果相同，返回包含
		if (ancestor == descendant) {
			return true;
		}
		// 由后代往上找
		Resource parent = descendant.getParent();
		while (parent != null) {
			if (parent == ancestor) {
				return true;
			}
			parent = parent.getParent();
		}
		return false;
	}
}